#include "variable.h"
#include <cmath>
#include <iostream>

variable::variable()
{
   main_value = 0;
   deci_value = 0;
   type = 'i'; // defaults to integer
}

variable::variable(int newmain, int newdeci, char newtype)
{
   main_value = newmain;
   deci_value = newdeci;
   type = newtype;
}

variable::variable(int value)
{
   main_value = value;
   deci_value = 0;
   type = 'i';
}

variable::variable(char value)
{
   main_value = value;
   deci_value = 0;
   type = 'c';
}

variable::variable(bool value)
{
   main_value = value;
   deci_value = 0;
   type = 'b';
}

variable::variable(variable & value)
{
   main_value = value.main_value;
   deci_value = value.deci_value;
   type = value.type;
}

variable::variable(variable::decimal value)
{
   main_value = std::floor(value);
   deci_value = std::fmod(value,1);
   type = 'f';
}

int variable::get_int()
{
   if ( type != 'i' && variable_h_warnings ) { std::cout << "WARNING: requesting an integer value from a noninteger variable" << std::endl; }
   return main_value;
}

char variable::get_char()
{
   if ( type != 'c' && variable_h_warnings ) { std::cout << "WARNING: requesting a character value from a non-character variable" << std::endl; }
   return char(main_value);
}

bool variable::get_bool()
{
   if ( type != 'b' && variable_h_warnings ) { std::cout << "WARNING: requesting a boolean value from a non-boolean variable" << std::endl; }
   return bool(main_value);
}

variable::decimal variable::get_float()
{
   if ( type != 'f' && variable_h_warnings ) { std::cout << "WARNING: requesting a floating point value from a non-float variable" << std::endl; }
   return variable::decimal(main_value) + deci_value;
}

variable & variable::operator= (const variable & other)
{
   if ( this == &other ) { return *this; }
   else if ( other.type != type && variable_h_warnings ) { std::cout << "WARNING: assigning variable a value of a different type" << std::endl; }
   main_value = other.main_value;
   deci_value = other.deci_value;
   type = other.type;
   return *this;
}

variable & variable::operator+= (const variable & other)
{
   if ( other.type != type && variable_h_warnings ) { std::cout << "WARNING: assigning variable a value of a different type" << std::endl; }
   main_value += other.main_value;
   deci_value += other.deci_value;
   if ( other.type == 'f' ) { type == 'f'; } // no way to add a float without becoming a float
   return *this;
}
